<template>
  <div class="dynamic-table">
    <!-- 工具栏 -->
    <div v-if="showToolbar" class="table-toolbar">
      <div class="toolbar-left">
        <div class="table-title" v-if="title">{{ title }}</div>
        <slot name="toolbar-left"></slot>
      </div>
      <div class="toolbar-right">
        <slot name="toolbar-right"></slot>
      </div>
    </div>

    <!-- 表格上方插槽 -->
    <div v-if="$slots['table-top']" class="table-top">
      <slot name="table-top"></slot>
    </div>

    <!-- 表格主体 -->
    <div class="table-content">
      <div class="table-left" v-if="$slots['table-left']">
        <slot name="table-left"></slot>
      </div>

      <div class="table-main">
        <el-table
          ref="tableRef"
          v-bind="tableBindProps"
          :data="data"
          :loading="loading"
          :height="height"
          :max-height="maxHeight"
          :border="border"
          :stripe="stripe"
          :size="size"
          :row-key="rowKey"
          :class="tableClass"
          @selection-change="handleSelectionChange"
          @current-change="handleCurrentChange"
          @sort-change="handleSortChange"
          @row-click="handleRowClick"
        >
          <!-- 选择列 -->
          <el-table-column
            v-if="selectionType === 'multiple'"
            type="selection"
            width="55"
            align="center"
            fixed="left"
          />
          <el-table-column
            v-else-if="selectionType === 'single'"
            width="55"
            align="center"
            fixed="left"
          >
            <template #default="{ row }">
              <el-radio
                :model-value="currentRow && currentRow[rowKey] === row[rowKey]"
                :label="true"
                @change="handleSingleSelect(row)"
              ></el-radio>
            </template>
          </el-table-column>

          <!-- 动态列 -->
          <el-table-column
            v-for="column in visibleColumns"
            :key="column.prop || column.label"
            v-bind="getColumnProps(column)"
          >
            <template #default="{ row, column: col, $index }">
              <!-- 插槽渲染 -->
              <slot
                v-if="column.slot"
                :name="column.slot"
                :row="row"
                :column="col"
                :index="$index"
                :value="row[column.prop]"
              ></slot>
              <!-- 函数渲染 -->
              <component
                v-else-if="column.render"
                :is="{ render: () => column.render!(row, col, row[column.prop], $index) }"
              />
              <!-- 默认渲染 -->
              <el-tooltip
                v-else
                :content="String(row[column.prop] || '')"
                placement="top"
                :disabled="
                  !row[column.prop] || String(row[column.prop]).length <= 30
                "
                popper-class="table-cell-tooltip"
              >
                <span class="table-cell-text">{{ row[column.prop] }}</span>
              </el-tooltip>
            </template>
          </el-table-column>
        </el-table>

        <!-- 分页 -->
        <div
          v-if="showPagination && pagination && pagination.total > 0"
          class="table-pagination"
        >
          <el-pagination
            v-bind="paginationProps"
            :current-page="pagination.currentPage"
            :page-size="pagination.pageSize"
            :total="pagination.total"
            @size-change="handleSizeChange"
            @current-change="handlePageChange"
          />
        </div>
      </div>

      <div class="table-right" v-if="$slots['table-right']">
        <slot name="table-right"></slot>
      </div>
    </div>

    <!-- 表格下方插槽 -->
    <div v-if="$slots['table-bottom']" class="table-bottom">
      <slot name="table-bottom"></slot>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, nextTick } from "vue";
import { ElTooltip } from "element-plus";
import type {
  DynamicTableProps,
  DynamicTableInstance,
  TableColumn,
  PaginationConfig,
} from "./types";

defineOptions({
  name: "DynamicTable",
});

const props = withDefaults(defineProps<DynamicTableProps>(), {
  data: () => [],
  columns: () => [],
  loading: false,
  border: true,
  stripe: true, // 修改为默认启用斑马纹
  size: "default",
  selectionType: "none",
  rowKey: "id",
  showPagination: true,
  showToolbar: true,
});

const emit = defineEmits<{
  "selection-change": [selection: any[]];
  "current-change": [currentRow: any, oldCurrentRow: any];
  "sort-change": [{ column: any; prop: string; order: string }];
  "size-change": [size: number];
  "current-page-change": [page: number];
  "row-click": [row: any, column: any, event: Event];
}>();

const tableRef = ref();
const currentRow = ref();
const selectedRows = ref<any[]>([]);

// 计算可见的列
const visibleColumns = computed(() => {
  return props.columns.filter((column) => column.show !== false);
});

// 表格绑定属性
const tableBindProps = computed(() => {
  return {
    ...props.tableProps,
    "highlight-current-row": props.selectionType === "single",
  };
});

// 分页组件属性
const paginationProps = computed(() => {
  if (!props.pagination) return {};

  return {
    pageSizes: props.pagination.pageSizes || [10, 20, 50, 100],
    layout:
      props.pagination.layout || "total, sizes, prev, pager, next, jumper",
    background: props.pagination.background ?? true,
    small: props.pagination.small || props.size === "small",
  };
});

// 获取列属性
const getColumnProps = (column: TableColumn) => {
  const { render, slot, show, ...rest } = column;
  return rest;
};

// 选择变化处理
const handleSelectionChange = (selection: any[]) => {
  selectedRows.value = selection;
  emit("selection-change", selection);
};

// 当前行变化处理
const handleCurrentChange = (currentRowData: any, oldCurrentRow: any) => {
  currentRow.value = currentRowData;
  emit("current-change", currentRowData, oldCurrentRow);
};

// 排序变化处理
const handleSortChange = (sortInfo: {
  column: any;
  prop: string;
  order: string;
}) => {
  emit("sort-change", sortInfo);
};

// 单选处理
const handleSingleSelect = (row: any) => {
  currentRow.value = row;
  selectedRows.value = [row];
  tableRef.value?.setCurrentRow(row);
  emit("selection-change", [row]);
  emit("current-change", row, null);
};

// 行点击处理
const handleRowClick = (row: any, column: any, event: Event) => {
  if (props.selectionType === "single") {
    handleSingleSelect(row);
  }
  emit("row-click", row, column, event);
};

// 分页大小变化
const handleSizeChange = (size: number) => {
  emit("size-change", size);
};

// 当前页变化
const handlePageChange = (page: number) => {
  emit("current-page-change", page);
};

// 清空选中
const clearSelection = () => {
  selectedRows.value = [];
  currentRow.value = null;
  tableRef.value?.clearSelection();
  tableRef.value?.setCurrentRow();
};

// 设置全选
const toggleAllSelection = () => {
  tableRef.value?.toggleAllSelection();
};

// 设置某一行的选中状态
const toggleRowSelection = (row: any, selected?: boolean) => {
  tableRef.value?.toggleRowSelection(row, selected);
};

// 获取选中的行数据
const getSelectionRows = () => {
  if (props.selectionType === "single") {
    return currentRow.value ? [currentRow.value] : [];
  }
  return selectedRows.value;
};

// 获取表格实例
const getTableRef = () => {
  return tableRef.value;
};

// 暴露方法给父组件
defineExpose<DynamicTableInstance>({
  clearSelection,
  toggleAllSelection,
  toggleRowSelection,
  getSelectionRows,
  getTableRef,
});
</script>

<style scoped lang="scss">
.dynamic-table {
  .table-toolbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 8px 0;
    margin-bottom: 8px;

    .toolbar-left {
      display: flex;
      align-items: center;
      gap: 16px;

      .table-title {
        font-size: 16px;
        font-weight: 500;
        color: var(--el-text-color-primary);
      }
    }

    .toolbar-right {
      display: flex;
      align-items: center;
      gap: 12px;
    }
  }

  .table-top {
    margin-bottom: 16px;
  }

  .table-content {
    display: flex;
    gap: 16px;

    .table-left {
      flex-shrink: 0;
    }

    .table-main {
      flex: 1;
      min-width: 0;
    }

    .table-right {
      flex-shrink: 0;
    }
  }

  .table-pagination {
    display: flex;
    justify-content: flex-end;
    margin-top: 16px;
  }

  .table-bottom {
    margin-top: 16px;
  }
}

// 表格单元格文本样式
:deep(.el-table) {
  .el-table__cell {
    padding: 8px 0;

    .table-cell-text {
      display: block;
      width: 100%;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      line-height: 1.4;
    }
  }

  // 确保表格行高一致
  .el-table__row {
    height: 40px;
  }

  // 表头样式
  .el-table__header-wrapper {
    .el-table__cell {
      padding: 8px 0;
      height: 40px;
    }
  }
}

// 全局样式，不使用scoped
</style>

<style lang="scss">
// 表格单元格tooltip样式
.table-cell-tooltip {
  max-width: 300px !important;
  word-wrap: break-word !important;
  word-break: break-all !important;
  white-space: normal !important;
  line-height: 1.4 !important;

  .el-tooltip__popper {
    max-width: 300px !important;
    word-wrap: break-word !important;
    word-break: break-all !important;
    white-space: normal !important;
    line-height: 1.4 !important;
  }
}
</style>
